package com.ganzi.ganziserver.service.imp;

import com.ganzi.ganziserver.core.*;
import com.ganzi.ganziserver.dao.FanCollectDao;
import com.ganzi.ganziserver.dao.FanInfromationDao;
import com.ganzi.ganziserver.dao.SchoolInformationDao;
import com.ganzi.ganziserver.dao.UserDao;
import com.ganzi.ganziserver.rabbit.send.SendUtil;
import com.ganzi.ganziserver.service.ControlLogService;
import com.ganzi.ganziserver.service.SendService;
import com.ganzi.ganziserver.shiro.redis.OtherCache.UserCache;
import com.ganzi.ganziserver.utils.ReturnMap;
import com.ganzi.ganziserver.utils.Topic;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class SendServiceImp implements SendService{
    private static Logger log = LoggerFactory.getLogger(SendServiceImp.class);

    @Autowired
    private FanInfromationDao fandao;
    @Autowired
    private SchoolInformationDao schooldao;
    @Autowired
    private SendUtil util;
    @Autowired
    ControlLogService logService;
    @Autowired
    FanCollectDao fanCollectDao;
    @Autowired
    UserDao userDao;
    @Autowired
    UserCache cache;
    /**
     * 发送单个盘管控制指令
     * */
    @Override
    public int sendOneControlMessage(long fanId, String type, String value) throws Exception {
        SendInformation info = fandao.findFanInformationByIdForSend(fanId);
        String infoid = UUID.randomUUID().toString();
        if(info != null && StringUtils.isNotBlank(info.getIp())){
            info.setType(type);
            info.setValue(value);
            info.setInfoId(infoid);
            info.setAllType(0);
            logService.saveLogForControl(fanId,type,value,1,"已发送",infoid);
            util.sendMessageToSchool(info);
            log.info("发送单个盘管控制指令："+info.toString());
            return 0;
        }else{
            String error = "没查询到SendInformation信息";
            logService.saveLogForControl(fanId,type,value,2,error,infoid);
            log.info("发送失败，没查询到SendInformation信息");
            return 1;
        }

    }

    /**
     * 发送多个盘管控制指令（针对一个学校）
     * */
    @Override
    public int sendManyControlMessage(long schoolId, String type, String value) throws Exception {
        OtherInformation otherInformationther = schooldao.findSchoolQueueById(schoolId);
        String infoid = UUID.randomUUID().toString();
        if(otherInformationther != null){
            SendInformation info = SendInformation.builder().channelName(otherInformationther.getChannelName()).build();
            info.setType(type);
            info.setValue(value);
            info.setInfoId(infoid);
            info.setAllType(1);

            //查询出全部采集器信息
            List<SendCollect> list = fanCollectDao.findFanCollectByschoolIdForSend(schoolId);
            info.setSendCollect(list);
            logService.saveLogForQuery(1,"已发送",infoid,schoolId,otherInformationther,Integer.parseInt(type),value);
            util.sendMessageToSchool(info);
            log.info("发送多个盘管控制指令："+info.toString());
            return 0;
        }else{
            String error = "学校消息队列不存在";
            logService.saveLogForQuery(2,error,infoid,schoolId,otherInformationther,Integer.parseInt(type),value);
            log.info("发送失败，学校消息队列不存在");
            return 1;
        }
    }

    /**
     * 查询单个学校的盘管状态信息
     * */
    @Override
    public int sendcollectionMessage(long schoolId) throws Exception {
        log.info(" 查询单个学校的盘管状态信息：学校id"+schoolId);
        return sendQueryOrState("0",schoolId);
    }

    /**
     * 查询单个学校和采集器的在线状态
     * */
    @Override
    public int sendStateMessage(long schoolId) throws Exception {
        log.info(" 查询单个学校和采集器状态信息：学校id"+schoolId);
        return sendQueryOrState("-1",schoolId);
    }

    /**
     * 查询全部学校和采集器的在线状态（这个是根据MQ的广播机制）
     * */
    @Override
    public int sendStateMessageByQueue() throws Exception {
        //学校和采集器状态全部设置成离线
        schooldao.changeSchoolState(2);
        fanCollectDao.changeCollectState(2);
        String infoid = UUID.randomUUID().toString();
        SendInformation info = SendInformation.builder().channelName(Topic.SCHOOL_STATE).build();
        info.setType("-1");
        info.setInfoId(infoid);
        info.setAllType(1);
        util.sendMessageToSchool(info);
        log.info("查询全部学校和采集器的在线状态通过广播机制："+info.toString());
        return 0;
    }

    /**
     * 查询全部学校和采集器的在线状态（这个是根据当前用户关联的学校轮询发送）
     * */
    @Override
    public int sendStateMessageByUser(boolean clean) throws Exception {
        //学校和采集器状态全部设置成离线
        if(clean){
            schooldao.changeSchoolState(2);
            fanCollectDao.changeCollectState(2);
        }
        Subject subject = SecurityUtils.getSubject();
        User tempUser = cache.getUserByPrincipal();
        boolean m = subject.isPermitted("allschool");
        List<Long> list;
        if(m){
            list = schooldao.findAllSchoolId();
        }else{
            list = userDao.findSchoolByUserId(tempUser.getId());
        }
        if(list != null && list.size()>0){
            for(int a=0;a<list.size();a++){
                sendStateMessage(list.get(a));
            }
            return 1;
        }
        return 0;
    }
    /**
     * 查询全部学校的采集器状态
     * */
    @Override
    public int sendStateMessageForCollection() throws Exception {
        //采集器状态全部设置成离线
        fanCollectDao.changeCollectState(2);
        String infoid = UUID.randomUUID().toString();
        SendInformation info = SendInformation.builder().channelName(Topic.SCHOOL_STATE).build();
        info.setType("-2");
        info.setInfoId(infoid);
        info.setAllType(1);
        logService.saveLogForQuery(1,"已发送",infoid,0,null,-2,"采集器状态");
        util.sendMessageToSchool(info);
        log.info(" 查询全部学校的采集器状态："+info.toString());
        return 0;
    }

    /**
     * 查询单个采集器上所有的盘管状态
     * */
    @Override
    public int sendQueryForCollection(String channelName,String ip,int count) throws Exception {
        String infoid = UUID.randomUUID().toString();
        SendInformation info = SendInformation.builder().channelName(channelName).build();
        info.setType("0");
        info.setInfoId(infoid);
        info.setAllType(1);
        SendCollect collect = SendCollect.builder().ip(ip).allCount(count).build();
        List<SendCollect> list = new ArrayList<>();
        list.add(collect);
        info.setSendCollect(list);
        util.sendMessageToSchool(info);
        log.info("采集盘管数据："+info.toString());
        return 0;
    }


    public int sendQueryOrState(String type,long schoolId)throws Exception{
        OtherInformation otherInformationther = schooldao.findSchoolQueueById(schoolId);
        String infoid = UUID.randomUUID().toString();
        if(otherInformationther != null){
            SendInformation info = SendInformation.builder().channelName(otherInformationther.getChannelName()).build();
            info.setType(type);
            info.setInfoId(infoid);
            info.setAllType(1);
            if("0".equals(type)){
                List<SendCollect> list = fanCollectDao.findFanCollectByschoolIdForSend(schoolId);
                info.setSendCollect(list);
            }
            logService.saveLogForQuery(1,"已发送",infoid,schoolId,otherInformationther,Integer.parseInt(type),"查询/获取学校状态");
            util.sendMessageToSchool(info);
            return 0;
        }else{
            String error = "学校消息队列不存在";
            logService.saveLogForQuery(2,error,infoid,schoolId,otherInformationther,Integer.parseInt(type),"查询/获取学校状态");
            log.info("发送失败，学校消息队列不存在");
            return 1;
        }
    }
}
